package main

import (
	"fmt"
	"os"
	"net"
	"io"
)

func SendFile(path string, conn net.Conn)  {
	//只读方式打开文件
	f, err := os.Open(path)
	if err != nil {
		fmt.Println(err)
		return
	}

	//使用完成之后关闭文件
	defer f.Close()

	buf := make([]byte, 1024 * 4)
	//使用for循环读取数据的原因是我们传文件时一般无法确认用户传输的文件大小，我们的切片是在定义时就指定了长度了的，所以要使用for循环去多次读取文件，
	//文件小了用的时间就短，文件大了用的时间就长，无非是循环次数的问题
	for  {
		n, err := f.Read(buf) //从文件读取内容
		if err != nil {
			if err == io.EOF {
				fmt.Println("文件读取完毕")
			}else {
				fmt.Println(err)
			}

			return
		}
		conn.Write(buf[:n]) //给服务器发送内容
	}
}

func main() {
	fmt.Println("请输入的需要传输的文件：")

	var path string
	fmt.Scan(&path)

	//获取文件名
	info, err := os.Stat(path)
	if err != nil {
		fmt.Println(err)
		return
	}
	name := info.Name()

	//连接服务器
	conn, err1 := net.Dial("tcp", "127.0.0.1:8000")
	if err1 != nil {
		fmt.Println(err1)
		return
	}

	//使用完之后关闭连接
	defer conn.Close()

	//给服务器发送文件名，这里丢弃发送长度这个返回值
	_, err2 := conn.Write([]byte(name))
	if err2 != nil {
		fmt.Println(err2)
		return
	}

	//接收方如果回复OK，可以发送文件
	buf := make([]byte, 1024)
	n, err3 := conn.Read(buf)
	if err3 != nil {
		fmt.Println(err3)
		return
	}
	if "ok" == string(buf[:n]) {
		SendFile(path, conn)
	}
}
